package com.zs.games.service.impl;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zs.games.resultTool.ResultCodeEnum;
import com.zs.games.entity.*;
import com.zs.games.exception.APIException;
import com.zs.games.mapper.*;
import com.zs.games.param.PageQuery;
import com.zs.games.param.UpdatePasswordParam;
import com.zs.games.param.UserIdParam;
import com.zs.games.service.GameInfoService;
import com.zs.games.service.GameNewsService;
import com.zs.games.service.UserInfoService;
import com.zs.games.utils.Base64SaltUtil;
import com.zs.games.utils.JwtTokenUtils;
import com.zs.games.vo.GameInfoVo;
import com.zs.games.vo.GameNewVo;
import com.zs.games.vo.LoginUserVo;
import com.zs.games.vo.UserBlackVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 
 * @date 2023年05月09日 17:18
 */
@Service
public class UserInfoServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo> implements UserInfoService {

    @Autowired
    private UserCollectNewsMapper userCollectNewsMapper;
    @Autowired
    private GameNewsService gameNewsService;
    @Autowired
    private GameInfoService gameInfoService;
    @Autowired
    private GameLiveMapper gameLiveMapper;
    @Autowired
    private UserFeedbackMapper userFeedbackMapper;
    @Autowired
    private UserBlackMapper userBlackMapper;
    @Override
    public boolean updateById(UserInfo entity) {
        entity.setUpdateTime(new Date());
        return super.updateById(entity);
    }

    @Override
    public boolean save(UserInfo entity) {
        List<UserInfo> userInfos = this.baseMapper.selectList(new QueryWrapper<UserInfo>()
                .lambda().eq(UserInfo::getUserName, entity.getUserName()));
        if (!userInfos.isEmpty()) {
            throw new APIException(ResultCodeEnum.USER_NAME_ALREADY_EXIST);
        }
        entity.setPassword(Base64SaltUtil.passwordEncode(entity.getPassword()));
        entity.setCreateTime(new Date());
        entity.setIsDeleted(0);
        entity.setStatus(1);
        return super.save(entity);
    }

    @Override
    public UserInfo getOne(Wrapper<UserInfo> queryWrapper) {
        return super.getOne(queryWrapper);
    }


    @Override
    public LoginUserVo getLoginUserInfo(String userName, String password) {
        String encodePassword = Base64SaltUtil.passwordEncode(password);
        UserInfo userInfo = this.baseMapper.getUserInfoByUserName(userName, encodePassword);
        if (userInfo == null) {
            throw new APIException(ResultCodeEnum.UNEXIST_ERROR);
        }
        LoginUserVo loginUserVo = new LoginUserVo();
        BeanUtils.copyProperties(userInfo, loginUserVo);
        String token = JwtTokenUtils.createToken(userInfo);
        loginUserVo.setToken(token);
        return loginUserVo;
    }

    @Override
    public Boolean logOut() {
        return true;
    }

    @Override
    public Boolean updatePassword(UpdatePasswordParam param) {
        String encodePassword = Base64SaltUtil.passwordEncode(param.getOldPassword());
        UserInfo userInfo = this.baseMapper.getUserInfoByUserName(param.getUserName(), encodePassword);
        if (userInfo == null) {
            throw new APIException(ResultCodeEnum.UNEXIST_ERROR);
        }
        userInfo.setPassword(Base64SaltUtil.passwordEncode(param.getNewPassword()));
        return baseMapper.updateById(userInfo) > 0;
    }

    @Override
    public List<GameNewVo> getCollectList() {
        ArrayList<GameNewVo> gameNewVos = new ArrayList<>();
        LoginUserVo userInfo = JwtTokenUtils.getUserInfoA();
        List<UserCollectNews> userCollectNews = userCollectNewsMapper.selectList(new QueryWrapper<UserCollectNews>().lambda().eq(UserCollectNews::getUserId, userInfo.getUserId()));
        for (UserCollectNews userCollectNew : userCollectNews) {
            GameNewVo gameNewsById = gameNewsService.getGameNewsById(userCollectNew.getNewId());
            if (gameNewsById != null && gameNewsById.getNewsId() != null){
                gameNewVos.add(gameNewsById);
            }

        }
        return gameNewVos;
    }

    @Override
    public List<GameInfoVo> getMyLiveGame() {
        ArrayList<GameInfoVo> gameInfoVos = new ArrayList<>();
        LoginUserVo userInfo = JwtTokenUtils.getUserInfoA();
        List<GameLive> userLiveGames = gameLiveMapper.selectList(
                new QueryWrapper<GameLive>().lambda().eq(GameLive::getUserId, userInfo.getUserId())
                        .eq(GameLive::getLiveStatus, 1)
        );
        for (GameLive gameLive : userLiveGames) {
            try {
                gameInfoVos.add(gameInfoService.getGameInfoById(gameLive.getGameId()));
            } catch (APIException e) {

            }
        }
        return gameInfoVos;
    }

    @Override
    public Boolean accountClose() {
        UserInfo userInfo = new UserInfo();
        userInfo.setUserId(JwtTokenUtils.getUserInfoA().getUserId());
        userInfo.setStatus(0);
        return this.baseMapper.updateById(userInfo) > 0;
    }

    @Override
    public Boolean feedBack(UserFeedback feedback) {
        if (feedback == null || feedback.getFeedbackId() == null){
            throw new APIException(ResultCodeEnum.PARAM_ERROR);
        }
        LoginUserVo loginUserVo = JwtTokenUtils.getUserInfoA();
        feedback.setCreateTime(new Date());
        feedback.setUserId(loginUserVo.getUserId());
        return userFeedbackMapper.insert(feedback) > 0;
    }

    @Override
    public Boolean addBlack(UserIdParam param) {
        LoginUserVo loginUserVo = JwtTokenUtils.getUserInfoA();
        // 判断是否已经拉黑
        Integer count = userBlackMapper.selectCount(new QueryWrapper<UserBlack>().lambda().eq(UserBlack::getUserId, loginUserVo.getUserId())
                .eq(UserBlack::getFriendUserId, param.getUserId()));
        if (count > 0){
            throw new APIException(ResultCodeEnum.ALREADY_EXIST);
        }
        return userBlackMapper.insert(new UserBlack(loginUserVo.getUserId(),param.getUserId())) > 0;
    }

    @Override
    public Boolean delBlack(UserIdParam param) {
        LoginUserVo loginUserVo = JwtTokenUtils.getUserInfoA();
        userBlackMapper.delete(new QueryWrapper<UserBlack>().lambda().eq(UserBlack::getUserId, loginUserVo.getUserId())
                .eq(UserBlack::getFriendUserId, param.getUserId()));
        return true;
    }

    @Override
    public IPage<UserBlackVo> getBlackList(PageQuery param) {
        LoginUserVo loginUserVo = JwtTokenUtils.getUserInfoA();

        return userBlackMapper.getUserBlackList(new Page<>(param.getPageNumber(), param.getPageSize()),loginUserVo.getUserId());

    }

}
